package com.quanyan.place.web.api;

import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.ApiResponseEnum;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.utils.DateTimeUtils;
import com.quanyan.common.utils.ServletUtils;
import com.quanyan.orderpay.request.ReqPayInfo;
import com.quanyan.orderpay.response.RespPreOrder;
import com.quanyan.place.biz.IBaseService;
import com.quanyan.place.cache.PlaceRedisTemplate;
import com.quanyan.place.constants.PlaceConstants;
import com.quanyan.place.entity.TbBizPlaceUnitSalePlan;
import com.quanyan.place.entity.TbCity;
import com.quanyan.place.entity.apireq.*;
import com.quanyan.place.entity.apiresp.RespBizPlaceBaseInfo;
import com.quanyan.place.entity.apiresp.RespCategoryAndScale;
import com.quanyan.place.entity.apiresp.RespSearchElements;
import com.quanyan.place.entity.apiresp.RespUserBizPlaceOrderInfo;
import com.quanyan.place.entity.vo.UnitSalePlan;
import com.quanyan.place.request.ReqCommentAdd;
import com.quanyan.place.response.RespPlaceElementsInfo;
import com.quanyan.place.service.*;
import com.quanyan.place.wrapper.PlaceMessageWrapper;
import com.quanyan.place.wrapper.PlaceOrderServiceWrapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections.Predicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * Created by yangyun on 16-5-25.
 */
@RestController
@RequestMapping("/api/place")
public class ApiPlaceController {
    private static final Logger logger = LoggerFactory.getLogger(ApiPlaceController.class);
    @Autowired
    ApiPlaceService apiPlaceService;

    @Autowired
    PlaceOrderServiceWrapper placeOrderServiceWrapper;

    @Autowired
    BaseService baseService;

    @Autowired
    IBaseService iBaseService;

    @Autowired
    PlaceInnerService placeService;
    @Autowired
    private PlaceBaseService placeBaseService;

    @Autowired
    PlaceMessageWrapper placeMessageWrapper;
    @Autowired
    private PlaceRedisTemplate placeRedisTemplate;

    /**
     * 增加ReqHibirdLog
     * @param reqHibirdLog
     * @return
     */
    @RequestMapping(value = "/addHibirdLog")
    public APIResponse<?> addHibirdLog(@RequestBody ReqHibirdLog reqHibirdLog) {

        return apiPlaceService.addHibirdLog(reqHibirdLog);
    }

    /**
     * 【排序5】结合场景预测推荐场馆
     * @param reqSearchVo
     * @return
     */
    @RequestMapping(value = "/recommendPlaceByUid")
    public APIResponse<?> recommendPlaceByUid(@RequestBody @Valid ReqSearchVo reqSearchVo){
        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer userId = (Integer)httpServletRequest.getAttribute("uid");
//        userId = 9009614;
        if (null == reqSearchVo.getLat() || null == reqSearchVo.getLng()){
            return APIResponse.returnFail("GPS定位失败");
        }
        if (StringUtils.isEmpty(reqSearchVo.getPageNum())){
            reqSearchVo.setPageNum(Constants.DEFAULT_PAGE_NUM);
        }
        return apiPlaceService.recommendPlaceByUid(userId, reqSearchVo);

    }

    @RequestMapping(value = "/newPlaceSearch")
    public APIResponse<PageObj<List<RespBizPlaceBaseInfo>>> newPlaceSearch(@RequestBody ReqSearchVo reqSearchVo){
        if (StringUtils.isEmpty(reqSearchVo.getSearchType())){
            return APIResponse.returnFail("搜索失败");
        }
        if (StringUtils.isEmpty(reqSearchVo.getPageNum())){
            reqSearchVo.setPageNum(Constants.DEFAULT_PAGE_NUM);
        }
        return apiPlaceService.newPlaceSearch(reqSearchVo);
    }

    /**
     * 搜索场地 placeSearch
     */
    @RequestMapping(value = "/placeSearch")
    public APIResponse<PageObj<List<RespBizPlaceBaseInfo>>> placeSearch(@RequestBody @Valid ReqSearchVo reqSearchVo){
        // 是否上架  现统一不去查询
//        reqSearchVo.setIsShelves(null);

        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer userId = (Integer) httpServletRequest.getAttribute("uid");
        if (null != userId){
            reqSearchVo.setUid(userId);
        }

        if (StringUtils.isEmpty(reqSearchVo.getSearchType())){
            return APIResponse.returnFail("搜索失败");
        }
        if (StringUtils.isEmpty(reqSearchVo.getPageNum())){
            reqSearchVo.setPageNum(Constants.DEFAULT_PAGE_NUM);
        }
        return apiPlaceService.placeSearch(reqSearchVo);
    }

    /**
     * 获取场馆评价项目 commentType
     * @param map
     * @return
     */
    @RequestMapping(value = "/commentType")
    public APIResponse<List<RespPlaceElementsInfo>> commentType(@RequestBody @Valid Map<String, Object> map,
                                                                BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        Integer placeId = MapUtils.getInteger(map, "placeId");
        if (!StringUtils.isEmpty(placeId)){
            return apiPlaceService.commentType(placeId);
        }else{
            return APIResponse.returnFail("placeId is null");
        }
    }

    /**
     * 场馆评价 comment
     * @param reqCommentAdd
     * @return
     */
    @RequestMapping(value = "/comment")
    public APIResponse<Integer> comment(@RequestBody @Valid ReqCommentAdd reqCommentAdd,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer userId = (Integer)httpServletRequest.getAttribute("uid");
        reqCommentAdd.setUid(userId);
        return apiPlaceService.comment(reqCommentAdd);
    }

    /**
     * 我的场馆收藏列表 collectList
     * @param map
     * @return
     */
    @RequestMapping(value = "/collectList")
    public APIResponse<PageObj<List<RespBizPlaceBaseInfo>>> collectList(@RequestBody @Valid Map<String, Object> map,
                                                                        BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }


        Integer uid = MapUtils.getInteger(map, "uid");
        Integer pageNum = MapUtils.getInteger(map, "pageNum");
        Integer pageSize = MapUtils.getInteger(map, "pageSize");
        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer userId = (Integer)httpServletRequest.getAttribute("uid");
        Double currLng = MapUtils.getDouble(map,"lng");//当前经度
        Double currLat = MapUtils.getDouble(map,"lat");//当前纬度
        uid = userId;
        if (StringUtils.isEmpty(currLng) || StringUtils.isEmpty(currLat)){
            return APIResponse.returnFail("经纬度不能为空");
        }
        if (!StringUtils.isEmpty(uid)){
            if (StringUtils.isEmpty(pageNum)){
                pageNum = Constants.DEFAULT_PAGE_NUM;
            }
            if (StringUtils.isEmpty(pageSize)){
                pageSize = Constants.DEFAULT_PAGE_SIZE;
            }
            return apiPlaceService.collectList(uid, currLng, currLat, pageNum, pageSize);
        }else{
            return APIResponse.returnFail("uid is null");
        }
    }

    /**
     * 收藏/取消场馆 collect
     * @param map
     * @return
     */
    @RequestMapping(value = "/collect")
    public APIResponse<Integer> collect(@RequestBody @Valid Map<String, Object> map,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        Integer uid = MapUtils.getInteger(map, "uid");
        Integer placeId = MapUtils.getInteger(map, "placeId");
        Integer type = MapUtils.getInteger(map, "type");

        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer userId = (Integer)httpServletRequest.getAttribute("uid");
        uid = userId;
        if (StringUtils.isEmpty(uid)){
            return APIResponse.returnFail("uid is null");
        }
        if (StringUtils.isEmpty(placeId)){
            return APIResponse.returnFail("placeId is null");
        }
        if (StringUtils.isEmpty(type)){
            return APIResponse.returnFail("type is null");
        }
        return apiPlaceService.collect(uid, placeId, type);
    }

    /**
     * 18、批量取消场馆 cancelPlaces
     * @param map
     * @return
     */
    @RequestMapping(value = "/cancelPlaces")
    public APIResponse<Integer> cancelPlaces(@RequestBody Map<String, Object> map) {
        Integer uid = MapUtils.getInteger(map, "uid");
        Object object = MapUtils.getObject(map, "ids");
        HttpServletRequest httpServletRequest = ServletUtils.getHttpServletRequest();
        Integer userId = (Integer)httpServletRequest.getAttribute("uid");
        uid = userId;
        if (StringUtils.isEmpty(object)) {
            return APIResponse.returnFail("没有需要取消场馆");
        }
        List<Integer> ids = (List<Integer>) object;
        return apiPlaceService.cancelPlaces(uid, ids);
    }

    /**
     * 根据经纬度获取城市对象
     * @param map
     * @return
     */
    @RequestMapping(value = "/getCity")
    public APIResponse<TbCity> getCity(@RequestBody @Valid Map<String, Object> map,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        Double lng = MapUtils.getDouble(map, "lng");//116.46
        Double lat = MapUtils.getDouble(map, "lat");//39.92

        return iBaseService.getCity(lng, lat);
    }

    /**
     * 获取搜索要素
     * @return
     */
    @RequestMapping(value = "/searchElements")
    public APIResponse<RespSearchElements> searchElements(@RequestBody @Valid Map<String, Object> map,BindingResult bindingResult){
        Integer clientType = MapUtils.getInteger(map, "clientType");
        Integer type = MapUtils.getInteger(map, "type");
        return apiPlaceService.searchElements(clientType, type);
    }

    @Autowired
    ApiPlaceOrderService apiPlaceOrderSerive;
    /**
     * 查看场馆基本信息
     * @param map
     * @return
     */
    @RequestMapping(value = "/placeBaseInfo")
    public APIResponse<?> placeBaseInfo(@RequestBody @Valid Map<String,Object> map){
        Integer placeId = MapUtils.getInteger(map,"placeId");
        return apiPlaceOrderSerive.getPlaceBaseInfo(placeId);
       // return apiPlaceService.placeBaseInfo(placeId);
    }

    /**
     * 查询订场计划
     * @param reqPlaceSalePlan
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/placeSalePlan")
    public APIResponse<?> placeSalePlan(@RequestBody @Valid ReqPlaceSalePlan reqPlaceSalePlan,
                                        BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return apiPlaceService.placeSalePlan(reqPlaceSalePlan);
    }

    /**
     * 查询订场计划 只返回组合场地
     * @param reqPlaceSalePlan
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/placeCombineSalePlan")
    public APIResponse<?> placeCombineSalePlan(@RequestBody @Valid ReqPlaceSalePlan reqPlaceSalePlan,
                                        BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return apiPlaceService.placeCombineSalePlan(reqPlaceSalePlan);
    }

    /**
     * 查看场馆详情
     * @param reqPlaceDetailInfo
     * @return
     */
    @RequestMapping(value = "/placeDetailInfo")
    public APIResponse<?> placeDetailInfo(@RequestBody @Valid ReqPlaceDetailInfo reqPlaceDetailInfo,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return apiPlaceService.placeDetailInfo(reqPlaceDetailInfo);
    }

    /**
     * 查看场馆评论列表
     * @param reqCommentList
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/commentList")
    public APIResponse<?> commentList(@RequestBody @Valid ReqCommentList reqCommentList,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return apiPlaceService.commentList(reqCommentList);
    }

    /**
     * 场次预定
     * @param reqPlaceOrderListVo
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/preOrder")
    public APIResponse<?> preOrder(@RequestBody @Valid ReqPlaceOrderListVo reqPlaceOrderListVo,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return placeOrderServiceWrapper.preOrder(reqPlaceOrderListVo);
    }

    /**
     * 场馆支付
     * @param reqPlaceOrderInfo
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/pay")
    public APIResponse<?> pay(@RequestBody @Valid ReqPlaceOrderInfo reqPlaceOrderInfo,BindingResult bindingResult){
	        if (bindingResult.hasErrors()) {
	            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
	        }
	    	try {
	    		// 判断是否为会员卡消费
	            List<ReqPayInfo> reqPayInfos = reqPlaceOrderInfo.getPayInfos();
	            boolean flag =  CollectionUtils.exists(reqPayInfos, new Predicate() {
	    			@Override
	    			public boolean evaluate(Object object) {
	    				ReqPayInfo reqPayInfo = (ReqPayInfo)object;
	    				return PlaceConstants.PAY_WAY_FOR_CARD.equals(reqPayInfo.getPayId());
	    			}
	    		});
	            if (flag){
	                if (null == reqPlaceOrderInfo.getCardNo() || StringUtils.isEmpty(reqPlaceOrderInfo.getCardNo())) {
	                    return APIResponse.returnFail("会员卡不能为空");
	                }
	                return placeOrderServiceWrapper.cardPay(reqPlaceOrderInfo);
	            }
	            APIResponse<RespPreOrder>  result= placeOrderServiceWrapper.pay(reqPlaceOrderInfo);
	            if (!StringUtils.isEmpty(reqPlaceOrderInfo.getTokenFlag())){
	                if (result.getErrcode()==200 && result.isRet()) {
	                    reqPlaceOrderInfo.setPlaceOrderId(result.getData().getOutTradeNo());
	                    try {
	                        placeMessageWrapper.promotionSave(reqPlaceOrderInfo);
	                    }catch (Exception e){
	                        e.printStackTrace();
	                        logger.error("推广下发短信存储异常"+e.getMessage());
	                    }
	                }
	            }
	            return result;
			} catch (BizException e) {
				logger.warn(e.getMessage(), e);
				return APIResponse.returnFail(e.getMessage());
			} catch (Exception e) {
				logger.error("app下单失败", e);
				return APIResponse.returnFail("网络异常，请稍后再试");
			}
    }
    
	private String startSalePlan(List<UnitSalePlan> tbBizPlaceUnitSalePlanList){
		List<String> redisKey = new ArrayList<String>();
		//还需要考虑组合场的情况
		for (UnitSalePlan unitSalePlan : tbBizPlaceUnitSalePlanList) {
			//设置锁 有效时间60秒 
			String flag = placeRedisTemplate.setnx(PlaceConstants.PLACE_SALE_UNIT + unitSalePlan.getSaleId(), "LOCK", 60);
			if (!"OK".equals(flag)) {//存在就回滚
			    TbBizPlaceUnitSalePlan tbBizPlaceUnitSalePlan = placeService.selectUnitSalePlanBySaleId(unitSalePlan.getSaleId());
				String errror = tbBizPlaceUnitSalePlan.getPlaceUnitName() + "的" +
								    DateTimeUtils.timeToStr(tbBizPlaceUnitSalePlan.getStartTime()) + "-" 
									+ DateTimeUtils.timeToStr(tbBizPlaceUnitSalePlan.getEndTime())+"时段已经售出！";
				for (String key : redisKey) {
					placeRedisTemplate.delteKey(key);
				}
				logger.info(errror);
				return errror;
			}
			redisKey.add(PlaceConstants.PLACE_SALE_UNIT + unitSalePlan.getSaleId());
		}
		return null;
	}
    
	private void completeSalePlan(List<UnitSalePlan> tbBizPlaceUnitSalePlanList){
		for (UnitSalePlan tbBizPlaceUnitSalePlan : tbBizPlaceUnitSalePlanList) {
			placeRedisTemplate.delteKey(PlaceConstants.PLACE_SALE_UNIT + tbBizPlaceUnitSalePlan.getSaleId());
		}
	}
	
    /**
     * 场馆订单状态处理
     * @param reqOrderOperate
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/orderOperate")
    public APIResponse<?> orderOperate(@RequestBody @Valid ReqOrderOperate reqOrderOperate,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        reqOrderOperate.setIsCallBackOrder(PlaceConstants.YES);
        reqOrderOperate.setCallBackType(2);
        return placeOrderServiceWrapper.orderOperate(reqOrderOperate);
    }

    /**
     * 用户订单列表
     * @param map
     * @return
     */
    @RequestMapping(value = "/userPlaceOrder")
    public APIResponse<PageObj<List<RespUserBizPlaceOrderInfo>>> userPlaceOrder(@RequestBody @Valid Map<String, Object> map){
        return apiPlaceService.userPlaceOrder(map);
    }
    
    /**
     * 获取支付信息
     * @param reqGetPayInfo
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/getPayInfo")
    public APIResponse<?> getPayInfo(@RequestBody @Valid ReqGetPayInfo reqGetPayInfo,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return placeOrderServiceWrapper.getPayInfo(reqGetPayInfo);
    }


    /**
     * 场馆订单支付
     * @param reqOrderPay
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/orderPay")
    public APIResponse<?> orderPay(@RequestBody @Valid ReqOrderPay reqOrderPay,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        APIResponse<RespPreOrder> result=placeOrderServiceWrapper.orderPay(reqOrderPay);
        //是否是推广下发短信的支付
        /*if (reqOrderPay.getTokenFlag()!=null){
            if (result.getErrcode()==200 && result.isRet()) {
                placeMessageWrapper.secondPromotionSave(reqOrderPay);
            }
        }*/
        return result;
    }


    /**
     * 通过订单号查询分享信息
     * @param reqOrderShare
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/orderShare")
    public APIResponse<?> orderShare(@RequestBody @Valid ReqOrderShare reqOrderShare,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return placeOrderServiceWrapper.orderShare(reqOrderShare);
    }

    /**
     *邀请用户接口
     * @param reqInviteUser
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/inviteUser")
    public APIResponse<?> inviteUser(@RequestBody @Valid ReqInviteUser reqInviteUser,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return placeOrderServiceWrapper.inviteUser(reqInviteUser);
    }


    /**
     * 获取场馆活动 / 比赛详情（首页使用）
     * @param reqActivityOrMatchDetail
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/activityOrMatchDetail")
    public APIResponse<?> activityOrMatchDetail(@RequestBody @Valid ReqActivityOrMatchDetail reqActivityOrMatchDetail,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return apiPlaceService.activityOrMatchDetail(reqActivityOrMatchDetail);
    }

    /**
     *获取场馆推荐的比赛或者活动
     * @param reqActivityOrMatchList
     * @param bindingResult
     * @return
     */
    @RequestMapping(value = "/activityOrMatchList")
    public APIResponse<?> activityOrMatchList(@RequestBody @Valid ReqActivityOrMatchList reqActivityOrMatchList,BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        return APIResponse.returnSuccess(apiPlaceService.activityOrMatchList(reqActivityOrMatchList));
    }


    /**
     * 如果传入的url参数不为空，返回url的短链接地址，否则返回分享界面的url地址
     * @param reqShareUrl
     * @return
     */
    @RequestMapping(value = "/shareUrl")
    public APIResponse<?> shareUrl(@RequestBody @Valid ReqShareUrl reqShareUrl){
        return apiPlaceService.shareUrl(reqShareUrl);
    }

    /**
     * 获取场馆场地规模
     * @param map
     * @return
     */
    @RequestMapping(value = "/getFieldScales")
    public APIResponse<TbCity> getFieldScales(@RequestBody @Valid Map<String, Object> map, BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return APIResponse.returnFail(ApiResponseEnum.PARAMETER_INVALID);
        }
        Integer placeId = MapUtils.getInteger(map, "placeId");

        return placeService.getFieldScales();
    }

    /**
     * 获取场馆运动项目及场地规模
     * @param map
     * @return
     */
    @RequestMapping(value = "/getCategoryAndScale")
    public APIResponse<List<RespCategoryAndScale>> getCategoryAndScale(@RequestBody  Map<String, Object> map){
        Integer placeId = MapUtils.getInteger(map, "placeId");
        if (StringUtils.isEmpty(placeId)){
            return APIResponse.returnFail("placeId不能为空");
        }
        return APIResponse.returnSuccess(placeBaseService.getCategoryAndScale(placeId, true));
    }


}
